Skip to content

📦 Monica WebDAV バックアップ形式仕様

概要

本仕様书は、Monica ローカル金庫が自動化された WebDAV バックアップやデータ転送を行う際に使用するアーカイブ構造、下位データフォーマット、および暗号化プロトコルを完全に定義します。このフレームワークにより、クロスプラットフォームでの高度な解析性能 と、一切の妥協のないプライバシーとセキュリティ が保証されます。


1. 総论 (Overview)

Monica の WebDAV バックアップメカニズムは、ユーザーのコアデータを標準の ZIP アーカイブ(暗号化されていない場合は .zip、高強度のバックアップ暗号化が有効な場合は .enc.zip)にバンドルします。

冗长で伝統的なバイナリデータベース(.db)の直接エクスポートとは異なり、このバックアップアーカイブは .json コアデータ.csv サマリー、および 主に暗号化されたメディアリソース(Images) から構成される疎結合なアーキテクチャを採用しています。これにより、将来的なクロスプラットフォーム間(Android/ブラウザ/デスクトップ)でのデータ監査の簡素化と、極めて精密な復元ワークフローを実現しています。


2. バックアップアーカイブのディレクトリ構造

標準的なバックアップ ZIP アーカイブを解凍した際の完全なツリー構造は以下の通りです:

text
/ (ルートディレクトリ)
├── passwords/                  # パスワード項目 (凝集度の高い個別JSON保存)
│   ├── password_1_1700000.json
│   └── password_2_1700001.json
├── notes/                      # セキュアノートチャンク
│   └── note_1.json
├── cards/                      # クレジットカードおよび身分証明書データ
│   └── bank_card_v1.json
├── authenticators/             # 2FA / TOTP 構成シード
│   └── totp_registry.json
├── images/                     # 暗号化されたバイナリメディア添付ファイル群
│   ├── encrypted_photo_sha256.bin
│   └── secure_doc_avatar.bin
├── summary.csv                 # データのインデックスと簡易監査用サマリー
└── metadata.json               # アーカイブのメタデータ、バージョン、およびハッシュ検証マニフェスト

3. コア JSON スキーマ仕様

3.1 metadata.json (環境およびマニフェスト)

各バックアップパッケージのルートには、環境と完全性を検証するためのメタデータファイルが含まれます:

json
{
  "version": "1.4.0",
  "client": "Monica for Android",
  "exportTimestamp": 1778956200000,
  "cryptoProvider": "AES-256-GCM",
  "manifest": {
    "passwords/password_1_1700000.json": "sha256_hash_string_aaa",
    "passwords/password_2_1700001.json": "sha256_hash_string_bbb"
  }
}

3.2 passwords/ 認証情報エンティティの構造例

各パスワードエンティティは、不必要な入れ子(ネスト)を避けるためにフラット化された高凝集な構造を維持します:

json
{
  "id": 1700000,
  "title": "GitHub 个人账户",
  "username": "Base64_Encrypted_Username_Payload",
  "password": "Base64_Encrypted_Password_Payload",
  "websiteUrl": "[https://github.com](https://github.com)",
  "categoryId": 2,
  "isFavorite": true,
  "ssoRefEntryId": -1,
  "totpSecret": "Base64_Encrypted_TOTP_Secret",
  "customFields": [
    {
      "fieldName": "Recovery_Key",
      "fieldValue": "Base64_Encrypted_Value",
      "isProtected": true
    }
  ],
  "lastModified": 1778956000000
}

4. 暗号化構造とペイロード管理

高強度暗号化が有効である場合、データの漏洩を防ぐために、圧縮ストリーム全体に対して落盤前(永続化前)に AES-256-GCM による全盤処理が課されます。

4.1 ファイルヘッダーの構造設計

暗号化されたバイナリファイル(.enc.zip)の最前方(ヘッダー)には、固有のマジックバイトシーケンスが厳格に結合されています:

オフセット範囲 (Byte)割り当てデータ定義役割・説明
0x00 - 0x0CMONICA_ENC_V1 (13字)フォーマット世代のバージョン識別用マジックナンバー
0x0D - 0x1CSalt (16字节)PBKDF2 鍵派生用の高エントロピーな動的ソルト
0x1D - 0x28IV (12字节)AES-256-GCM 暗号化用の初期化ベクトル
0x29 - 末尾Ciphertext後続の完全に暗号化された ZIP バイナリストリームペイロード

4.2 ストリーム暗号化の擬似ロジック

kotlin
val derivedKey = PBKDF2.derive(backupPassword, salt, iterations = 100000)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(derivedKey, "AES"), GCMParameterSpec(128, iv))

val encryptedData = cipher.doFinal(rawZipBytes)
outputStream.write(MAGIC_BYTES)
outputStream.write(salt)
outputStream.write(iv)
outputStream.write(encryptedData)

5. クロスデバイス復元および衝突緩和ロジック

データの復元(レストア)フェーズにおいて、クライアントのランタイムは以下のシーケンシャルなパイプラインを厳格に実行します:

5.1 ライフサイクル実行ステップ

  1. 復号と検証.enc.zip をデコード ➔ ヘッダーブロックの完全性を検証 ➔ マスターパスワード派生キーを介してストリームを復号 ➔ メモリ内の隔離されたサンドボックス(Temp空間)にファイルを展開。
  2. ID 衝突の解決
  • 抽出された JSON 項目の主キー id が、現在デバイス上でアクティブなデータベース内に既に存在していることが判明した場合、エンジンは直接的な上書き(データ汚染)を拒否します。
  • 代替ルート(フォールバック)をトリガー:インポートされるレコードに対して、現在のタイムスタンプベースの新しい物理的なユニーク Long ID を再割り当てし、データベースに安全に新規挿入(Insert)します。
  1. 関係グラフの再構築(ID マッピング修復)
  • ランタイムルーチンは、一時的な 古いID ➔ 新しいID の対応関係マップ(マッピング表)をメモリ上にコンパイルします。
  • ssoRefEntryId パラメータ、ペア化されたアカウントインジケータ、および関連する TOTP バインド関係を自動的にスキャン・パッチ(修復)し、データ構造の整合性を壊すことなく関係グラフの結合関係を100%維持します。
  1. メディア資産の再配置
  • images/ ディレクトリツリー内のすべてのバイナリレコードを処理します。
  • スナップショットやドキュメントの添付ファイルを、ホストアプリの隔離されたローカルファイルシステム空間(context.filesDir)へ安全に移行し、アクティブなノートデータベース内の対応する内部パスバインドを書き換えます。

6. 例外処理(サーキットブレーカー制度)

  • 整合性の破壊:解凍時に metadata.json 内のマニフェストハッシュと実際の JSON ハッシュが一致しない場合、インポートタスクは即座に中断され、ローカルデータベースは自動的に Transaction Rollback(トランザクション・ロールバック)を実行して整合性を保護します。
  • 暗号化エラー:パスワードが間違っている、または AEAD 認証タグの検証に失敗した場合、メモリ内の鍵バッファは直ちにクリア(ゼロクリア)され、不完全な明文データがディスクに書き込まれるのを防ぎます。
最近更新